/**
 * 
 */
package org.statewalker.tokenizer.base;

import org.statewalker.tokenizer.stream.ICharStream;
import org.statewalker.tokenizer.stream.ICharStream.IMarker;

public abstract class SimpleTokenizer<T> extends AbstractTokenizer<T> {

    public SimpleTokenizer(ITokenFactory<T> factory) {
        super(factory);
    }

    protected abstract boolean checkChar(char ch, int pos);

    protected int getMaxLength() {
        return Integer.MAX_VALUE;
    }

    protected int getMinLength() {
        return 1;
    }

    public T read(ICharStream stream) {
        char ch = stream.getChar();
        int localPos = 0;
        if (!checkChar(ch, localPos))
            return null;
        T result = null;
        IMarker marker = stream.markPosition();
        try {
            int minLen = getMinLength();
            int maxLen = getMaxLength();
            if (stream.incPos()) {
                localPos++;
                while (localPos < maxLen
                    && checkChar(stream.getChar(), localPos)) {
                    if (!stream.incPos())
                        break;
                    localPos++;
                }
            }
            result = localPos >= minLen - 1 ? newToken(stream, marker) : null;
            return result;
        } finally {
            marker.close(result == null);
        }
    }
}